﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GameStateManagement;
using BHG.System;


namespace BHG.GameData
{
    class Level04 : GameplayScreen
    {
        protected const float DOOR_TIME = 2f;
        Model pavementFloor;
        Model door;
        Song song;
        List<CubeObject> hidenCubeObjects;
        List<CubeObject> doors;
        List<float> doorsYPosition;
        float doorsTimer;

        public override void LoadContent()
        {
            base.LoadContent();
            MediaPlayer.Stop();
            pavementFloor = content.Load<Model>("Models/Lands/Pavement/chodnik1");
            door = content.Load<Model>("Models/Walls/metal-wall1");
            player.Position = new Vector2(10, 150);
            this.CreateShowInfobar();
            song = content.Load<Song>("Sound/music/10 Endless 82 Master");

            gravityGunAllowed = true;
            blackHoleGunAllowed = true;
            MediaPlayer.Play(song);

            hidenCubeObjects = new List<CubeObject>();
            doors = new List<CubeObject>();
            doorsYPosition = new List<float>();
            doorsTimer = DOOR_TIME;

            this.BaseLand(0, 0, 5);
            this.HideBaseLand(60, -30, 2);
            this.HideBaseLand(85, -22, 1);
            this.HideBaseLand(100, -14, 1);
            this.HideBaseLand(115, 0, 1);
            this.BaseLand(130, 25, 10);
            this.Door(20, 15);
            this.Door(30, 15);
            this.Door(150, 40);
            GraphicObject temp = new GraphicObject(
                new Vector2(230, 30),
                BlackHoleModel,
                0);
            temp.RotationPerSecond = new Vector3(0.1f, 0.5f, 0.3f);
            objectsOnMap.Add(temp);
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            // generic update, update physics, call only once
            base.Update(gameTime, otherScreenHasFocus, false);
            checkHiddenObjects();
            checkDoors(gameTime);
            checkDeathByDoors();

            if (player.Position.X > 230)
            {
                LoadingScreen.Load(ScreenManager, true, PlayerIndex.One, CurrentGame.createNewLevel(5));
            }

            if (player.Position.Y < -50)
            {
                Death();
            }
        }


        /// <summary>
        /// Create the base objects where you can walk
        /// </summary>
        /// <param name="positionX"></param>
        /// <param name="positionY"></param>
        public void BaseLand(float positionX, float positionY, int count)
        {

            //Here you can walk
            float thick = 10f;
            float thickUp = 1f;
            for (int i = 0; i < count; i++)
            {
                objectsOnMap.Add(new CubeObject(
                    new Vector2(
                        positionX + i * thick,
                        positionY),
                    new Vector2(
                        thick,
                        thickUp),
                    false,
                    pavementFloor
                    ));
            }
        }

        public void HideBaseLand(float positionX, float positionY, int count)
        {
            //Here you can walk
            float thick = 10f;
            float thickUp = 1f;
            for (int i = 0; i < count; i++)
            {
                CubeObject o = new CubeObject(
                    new Vector2(
                        positionX + i * thick,
                        positionY),
                    new Vector2(
                        thick,
                        thickUp),
                    false,
                    pavementFloor);
                o.Hide = true;
                objectsOnMap.Add(o);
                hidenCubeObjects.Add(o);
            }
        }

        public void checkHiddenObjects()
        {
            foreach(CubeObject o in hidenCubeObjects)
            {
                if (Math.Abs(player.Position.X - o.Position.X) < 15)
                {
                    o.Hide = false;
                    //o.Life = 2;
                }
            }
        }

        public void Door(float positionX, float positionY)
        {
            CubeObject o = new CubeObject(
                    new Vector2(
                        positionX,
                        positionY),
                    new Vector2(
                        1,
                        30
                        ),
                    false,
                    door
                    );
            o.Dislocation = new Vector3(0f, -15f, 0f);
            objectsOnMap.Add(o);
            doors.Add(o);
            doorsYPosition.Add(o.Position.Y);
            o.SpeedPerSecond = new Vector3(0, 10, 0);
        }

        public void checkDoors(GameTime gameTime)
        {
            doorsTimer -= (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (doorsTimer < 0)
            {
                doorsTimer = DOOR_TIME;
                foreach (CubeObject o in doors)
                {
                    if (o.SpeedPerSecond.Y > 0) 
                    {
                        o.SpeedPerSecond = new Vector3(0, -10, 0);
                    } else {
                        o.SpeedPerSecond = new Vector3(0, 10, 0);
                    }
                    
                }
            }
        }

        public void checkDeathByDoors()
        {
            foreach (CubeObject o in doors)
            {
                int index = doors.IndexOf(o);
                if ((Math.Abs(o.Position.Y - doorsYPosition.ElementAt(index)) < 10) && (Math.Abs(o.Position.X - player.Position.X) < 2) && (o.SpeedPerSecond.Y < 0))
                {
                    Death();
                }
            }
        }

        public void Death()
        {
            LoadingScreen.Load(ScreenManager, true, PlayerIndex.One, CurrentGame.createNewLevel(4));
        }

    }
}
